package com.xtsoft.platform.base.system.controller;

import com.fasterxml.jackson.databind.JsonMappingException;

import com.xtsoft.core.common.Constants;
import com.xtsoft.core.controller.GenericController;
import com.xtsoft.core.repository.QueryFilter;
import com.xtsoft.core.repository.QueryResult;
import com.xtsoft.core.repository.Sort;
import com.xtsoft.core.utils.BeanUtil;
import com.xtsoft.core.utils.HeaderUtil;
import com.xtsoft.core.utils.ResultMsg;
import com.xtsoft.core.utils.StringUtils;
import com.xtsoft.platform.base.system.domain.ResourceRole;
import com.xtsoft.platform.base.system.domain.SysResource;
import com.xtsoft.platform.base.system.domain.SysRole;
import com.xtsoft.platform.base.system.domain.SysUser;
import com.xtsoft.platform.base.system.service.SysResourceService;
import com.xtsoft.platform.base.system.service.SysRoleService;
import com.xtsoft.platform.globe.enums.YesNo;
import com.xtsoft.platform.globe.utils.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.json.JsonParseException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName:  SysResource 
 * @Author author
 * @Vesion 1.0 Create Time:
 *         <p>
 *         <b>Class Description:</b>[TODO]
 *         <p>
 *         REST controller for managing sysResource.
 */


@Tag(name = "系统资源--处理接口")
@RestController
public class SysResourceController extends GenericController {

	private final Logger log = LoggerFactory.getLogger(SysResourceController.class);

	@Autowired
	private SysResourceService sysResourceService;
	@Autowired
	private SysRoleService sysRoleService;

	/**
	 * 功能：新增一个实体，POST请求
	 * 
	 * 路径： /sysResource/add
	 *
	 * @param sysResource 要新增的实体
	 * @return ResponseEntity, json格式,http status 201 表示成功 , html body中包含
	 *         sysResource 若sysResource存在主键值, 则http status 400 (Bad Request)
	 * @throws URISyntaxException 如果URI语法不正确，则抛URI语法异常
	 */
	
	@Parameter(name = "sysResource", description = "系统资源", required = false)
	@Operation(summary  = "新增系统资源记录")
	@PostMapping("/sysResource/add")
	public ResponseEntity<SysResource> add(@RequestBody SysResource sysResource) throws URISyntaxException {
		SysUser user = (SysUser) SecurityUtils.getLoginedUser();
		if (!StringUtils.isEmpty(sysResource.getResUniqueId())) {
			log.info("新增一条资源记录失败", user.getLoginId(), user.getUsername(), getClientIp());
			return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert("sysResource", "idexists",
					"A new sysResource cannot already have an ID")).body(null);
		}
		sysResource.setIsDesktop(YesNo.No.getIntValue());
		sysResource.setIsQuickLaunch(YesNo.No.getIntValue());
		sysResource.setResourceName(sysResource.getResourceNick());
		sysResource.setState(YesNo.Yes.getIntValue());
		if (sysResource.getButtonClr() == null || sysResource.getButtonClr().equals("")) {
			sysResource.setButtonClr("soft-blue");
		}
		SysResource result = sysResourceService.save(sysResource);
		log.info("成功新增一条资源记录", user.getLoginId(), user.getUsername(), getClientIp());
		return ResponseEntity.created(new URI("/sysResource/get/" + result.getResUniqueId()))
				.headers(HeaderUtil.createEntityCreationAlert("sysResource", result.getResUniqueId().toString()))
				.body(result);
	}

	/**
	 * <p>
	 * 更新一个资源
	 * </p>
	 * 
	 * @param sysResource 要更新的资源
	 * @return ResponseEntity<ResultMsg>, json格式
	 * @throws URISyntaxException 如果URI语法不正确，则抛URI语法异常
	 * @author Codegen-代码生成器
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 * @date 2020-05-31 23:22:05
	 */
	@Parameter(name = "sysResource", description = "要更新的资源", required = false)
	@Operation(summary  = "更新，根据传递的 资源更新实体")
	@PostMapping("/sysResource/update")
	
	public ResponseEntity<ResultMsg> update(
			@RequestBody SysResource sysResource)
			throws URISyntaxException, IllegalAccessException, InvocationTargetException {
		if (null == sysResource) {
			return new ResponseEntity<ResultMsg>(new ResultMsg(false, "更新资源失败，传递的资源为空"), HttpStatus.OK);
		}
		SysUser user = (SysUser) SecurityUtils.getLoginedUser();
		log.info("单条更新资源开始......",user.getLoginId(), user.getUsername(),
				getClientIp());
		// 若 资源无主键值，说明调用错误
		if (StringUtils.isBlank(sysResource.getResUniqueId())) {
			log.info("单条更新资源失败，资源对象ResUniqueId无属性值",user.getLoginId(),
					user.getUsername(), getClientIp());
			return new ResponseEntity<ResultMsg>(new ResultMsg(false, "更新失败，资源对象ResUniqueId无属性值"), HttpStatus.OK);
		}
		SysResource resource = sysResourceService.get(sysResource.getResUniqueId());
		BeanUtil.copyNotNullProperties(resource, sysResource);
		SysResource result = sysResourceService.save(resource);
		log.info("单条更新资源成功", user.getLoginId(),user.getUsername(), getClientIp());
		return new ResponseEntity<ResultMsg>(new ResultMsg(true, "更新成功", result), HttpStatus.OK);
	}

	/**
	 * 功能：获取分页的实体集合，GET请求
	 * 
	 * 路径： /sysResource/getAll
	 *
	 * @return the ResponseEntity, json格式， http status 200 表示成功 , html body中包含
	 *         SysResource的 list集合
	 * @throws URISyntaxException   如果出错，则产生页码信息的 HTTP headers
	 * @throws ParseException
	 * @throws IOException
	 * @throws JsonMappingException
	 * @throws JsonParseException
	 */
	@Operation(summary  = "获取资源列表")
	@GetMapping("/sysResource/getAll")
	public ResponseEntity<QueryResult<SysResource>> getAll()
			throws URISyntaxException, ParseException, JsonParseException, JsonMappingException, IOException {
		log.debug("REST request 获取页：SysResource");
		QueryFilter filter = new QueryFilter(SysResource.class);
		filter.addFilterFromRequest(request);
		filter.addSort("serialNo", Sort.ASC);
		// filter.addFilter("Q_resourceType_I_NEQ", "1");// 只查询按钮或URL
		QueryResult<SysResource> result = sysResourceService.anyQuery(filter);
		return new ResponseEntity<>(result, HttpStatus.OK);
	}

	/**
	 * <p>
	 * 根据角色唯一ID值获取角色
	 * </p>
	 * 
	 * @param id 角色唯一ID值
	 * @return ResponseEntity<SysResource>
	 * @author Codegen-代码生成器
	 * @date 2020-05-31 23:22:05
	 */
	@Parameter(name = "id", description = "对象唯一Id", required = false)
	@Operation(summary  = "获取单个资源，若根据资源唯一Id获取到了多个对象则发生异常")
	@GetMapping("/sysResource/get/{id}")
	
	public ResponseEntity<ResultMsg> get(
			@PathVariable String id) {
		if (StringUtils.isBlank(id)) {
			return new ResponseEntity<ResultMsg>(new ResultMsg(false, "获取单个资源失败，未给定资源的唯一标识"), HttpStatus.OK);
		}
		SysUser user = (SysUser) SecurityUtils.getLoginedUser();
		log.info("获取资源开始......", user.getLoginId(),user.getUsername(),
				getClientIp());
		SysResource sysResource = sysResourceService.get(id);
		/*
		 * <p> ofNullable执行逻辑：如果对象为空，则执行orElse，否则执行.map... return
		 * Optional.ofNullable(sysRole).map(result -> new ResponseEntity<>(result,
		 * HttpStatus.OK)) .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
		 */

		if (null == sysResource) {
			log.info("获取资源失败", user.getLoginId(), user.getUsername(), getClientIp());
			return new ResponseEntity<ResultMsg>(new ResultMsg(false, "获取单个资源失败，给定的资源可能被删除"), HttpStatus.OK);
		}
		log.info("获取资源成功", user.getLoginId(), user.getUsername(), getClientIp());
		return new ResponseEntity<ResultMsg>(new ResultMsg(true, "获取成功", sysResource), HttpStatus.OK);
	}

	/**
	 * 功能：构建资源选择grid
	 *
	 * 路径： /sysResource/getCheckGrid
	 * 
	 * @param id 实体主键值
	 * @return ResponseEntity,json格式, http status 200 (OK)
	 */

	@Operation(summary  = "构建资源选择grid")
	@GetMapping("/sysResource/getCheckGrid")
	public ResponseEntity<QueryResult<SysResource>> checkGrid()
			throws URISyntaxException, ParseException, JsonParseException, JsonMappingException, IOException {
		QueryFilter filter = new QueryFilter(SysResource.class);
		filter.addFilterFromRequest(request);
		filter.addFilter("Q_resourceType_I_NEQ", "1");// 只查询按钮或URL
		filter.addSort("serialNo", Sort.ASC);
		QueryResult<SysResource> result = sysResourceService.anyQuery(filter);
		SysRole sysRole = sysRoleService.get(request.getParameter("roleId"));
		if (null != sysRole) {
			List<ResourceRole> resourceRoles = sysRole.getResourceRoles();
			List<SysResource> sysResources = new ArrayList<SysResource>();
			for (ResourceRole resourceRole : resourceRoles) {
				sysResources.add(resourceRole.getSysResource());
			}
			for (SysResource sysResource : result.getResultList()) {
				if (sysResources.contains(sysResource)) {
					sysResource.setDescript("true");
				} else {
					sysResource.setDescript("false");
				}
			}
		}
		return new ResponseEntity<>(result, HttpStatus.OK);
	}


	/**
	 * <p> 获取功能按钮  </p>  
	 * @param preResourceId
	 * @return
	 * @return ResponseEntity<String>
	 * @throws  
	 * @author tuyingchao 
	 * @date 2020年6月4日 
	 * @time 下午7:42:02
	 */
	@Parameter(name = "preResourceId", description = "预资源Id", required = false)
	@Operation(summary  = "获取功能按钮")
	@GetMapping("/sysResource/getResourceButton/{preResourceId}")
	public ResponseEntity<String> getResourceButton(@PathVariable String preResourceId) {
		SysUser sysUser = (SysUser) SecurityUtils.getLoginedUser();
		return new ResponseEntity<>(sysResourceService.getResourceButton(sysUser, preResourceId), HttpStatus.OK);
	}

	/**
	 * <p>
	 * 根据资源唯一ID值删除资源，同时删除资源角色映射
	 * </p>
	 * 
	 * @param id 资源唯一ID值
	 * @return ResponseEntity,json格式
	 * @author Codegen-代码生成器
	 * @date 2020-05-29 13:12:51
	 */
	@Parameter(name = "id", description = "资源唯一Id", required = false)
	@Operation(summary  = "删除资源")
	@GetMapping("/sysResource/delete/{id}")

	public ResponseEntity<ResultMsg> delete(
 @PathVariable String id) {
		SysUser sysUser = (SysUser) SecurityUtils.getLoginedUser();
		log.info("删除资源开始......", sysUser.getLoginId(), sysUser.getUsername(),
				getClientIp());
		if (StringUtils.isBlank(id)) {
			return new ResponseEntity<ResultMsg>(new ResultMsg(false, "删除失败，传递的资源唯一标识为空"), HttpStatus.OK);
		}
		ResultMsg result = sysResourceService.deleteResources(id);
		log.info("删除资源成功", sysUser.getLoginId(), sysUser.getUsername(), getClientIp());
		return new ResponseEntity<>(result, HttpStatus.OK);
	}
	
	/**
	 * 
	 * <p> 获取右键菜单  </p>  
	 * @param preResourceId
	 * @return
	 * @return ResponseEntity<String>
	 * @throws  
	 * @author litao
	 * @date 2022年3月4日 
	 * @time 下午1:33:02
	 */
	@Parameter(name = "preResourceId", description = "预资源Id", required = false)
	@Operation(summary  = "获取右键菜单")
	@GetMapping("/sysResource/getContextMenu/{preResourceId}")
	public ResponseEntity<String> getContextMenu(@PathVariable String preResourceId) {
		SysUser sysUser = (SysUser) SecurityUtils.getLoginedUser();
		return new ResponseEntity<>(sysResourceService.getContextMenu(sysUser, preResourceId,false), HttpStatus.OK);
	}
	
	/**
	 * 
	 * <p> 获取列表右键菜单  </p>  
	 * @param preResourceId
	 * @return
	 * @return ResponseEntity<String>
	 * @throws  
	 * @author litao
	 * @date 2022年3月4日 
	 * @time 下午1:33:02
	 */
	@Parameter(name = "preResourceId", description = "预资源Id", required = false)
	@Operation(summary  = "获取右键菜单")
	@GetMapping("/sysResource/getContextViewMenu/{preResourceId}")
	public ResponseEntity<String> getContextViewMenu(@PathVariable String preResourceId) {
		SysUser sysUser = (SysUser) SecurityUtils.getLoginedUser();
		boolean isView = true;
		return new ResponseEntity<>(sysResourceService.getContextMenu(sysUser, preResourceId,isView), HttpStatus.OK);
	}
}
